#ifndef GRAPHFLOW_H
#define GRAPHFLOW_H
#include <iostream>
#include "graphtypes.h"
#include "GraphOriented.h"

using namespace std;

class GraphFlow : public virtual GraphOriented
{
protected :
  bool isResidual = false;
public :
  GraphFlow();
  GraphFlow(summit_t, edges_t);
  virtual ~GraphFlow();
  virtual flow_t getNetworkFlow() const;
  virtual flow_t getFlow(summit_t, summit_t) const=0;
  virtual void setFlow(summit_t, summit_t, flow_t)=0;
  virtual flow_t getCapacity(summit_t, summit_t) const=0;
  virtual void setCapacity(summit_t, summit_t, flow_t)=0;
  virtual flow_t getMaxCapacity() const;
  virtual void fill(flow_t min_c=1, flow_t max_c=10);
  virtual void updateResidualGraph(vector<summit_t> * path, flow_t k);
  virtual vector<summit_t> * notSaturatedShortestPath() const;
  virtual vector<summit_t> * notSaturatedShortestPath(summit_t a, summit_t b) const;
  virtual vector<summit_t> * notSaturatedPath(summit_t a, summit_t b) const;
  virtual vector<summit_t> * notSaturatedPath() const;
  virtual vector<summit_t> * onePathCapacityScaling(summit_t a, summit_t b, flow_t cmin) const;
  virtual vector<summit_t> * onePathCapacityScaling(flow_t cmin) const;
  virtual flow_t lowestDelta(vector<summit_t> * path) const;
  virtual flow_t lowestDelta(vector<summit_t> * path, summit_t & i, summit_t & j) const;
  virtual flow_t doEdmondsKarp();
  virtual flow_t doDinic();
  virtual flow_t doFordFulkerson();
  virtual flow_t doCapacityScaling();
  //virtual GraphOriented * createLevelGraph() const;
  //virtual bool areConnected(summit_t i, summit_t j) const;
  //virtual vector<summit_t> * getNeighbours(summit_t v) const;
};

#endif
